Oracle Spatial

Az ORACLE számos meghívható SPATIAL függvénnyel rendelkezik. Könnyen kiszámítható két objektum közötti távolság (SDO_NN_DISTANCE), lekérdezhető hogy egy pont objektum egy poligonon belül található-e (SDO_POINTINPOLYGON), készíthetünk olyan elemzést, amelybe csak egy adott távolságon belüli geometriákat emelünk be (SDO_WITHIN_DISTANCE), illetve van még számos egyéb térbeli lekérdezést szolgáló beépített függvény, amelyekkel ugyan desktop térinformatikai szoftverek user friendly módon rendelkeznek, viszont mi, mivel közvetlenül adatbázisban futtatunk lekérdezéseket, sokkal inkább személyre szabhatjuk a folyamatokat. A rendelkezésre álló spatial query-kről bővebben lásd a mellékelt linken.

Fókuszáljunk kicsit az SDO_NN függvényre, amely egy objektum legközelebbi szomszédját adja vissza. Azaz ha pl. arra vagyunk kíváncsiak, hogy egy adott bolthoz mely más boltok vannak térben a legközelebb, akkor érdemes ezt a függvényt használni. Futtatása során 4 paramétert vár:

- geometry1: az adatbázisunkban azt a geometriát adjuk itt meg, aminek a szomszédját/szomszédjait keressük

- geometry2: itt is egy geometriát adunk meg (többnyire ugyanazt a mezőt az adatbázisban, mint a geometry1 esetében). Ezzel jelezzük, hogy mely mezők között keressük a legközelebbi szomszédokat. - param: meg tudunk adni további feltételeket, hogy miszerint történjen a lekérdezés, lásd kicsit lejjebb. - number: ha az SDO_NN_DISTANCE-et is használjuk (azaz vizsgáljuk a távolságot) akkor a geometriák közötti távolságot is megadhatjuk szűrési feltételként

A param mező lehetséges értékei:

- distance=x: mekkora távolságig vizsgálja a szomszédokat, pl. 'distance=10 unit=mile' esetében 10 méerföldön belül történik a leválogatás

- sdo_batch_size: a rekordok elvárt eredményszámát tudjuk itt beállítani, azaz ha a 10 legközelebbi szomszédot keresünk adott geometriához képest, akkor 'sdo_batch_size=10' a helyes érték. Bővebben lejjebb.

- sdo_num_res: hasonlóan az előzőhöz, itt is a szükséges eredményszámot tudjuk itt beállítani, a kettő közötti különbségről lejjebb.

- unit: a distance parancs vagy az SDO_NN_DISTANCE használatánál a távolság mértékegységét adhatjuk meg, pl. 'unit=KM'

Az sdo_num_res-t akkor érdemes használni, ha nem akarunk a visszaadott értékek között szűrni, azaz ha minden szomszédos boltra kíváncsiak vagyunk és pl. nem csak a szomszédos TESCO-kat akarjuk látni. Az sdo_batch_size esetén viszont tudunk szűrni a mezőkre, illetve arra is, hogy egy adott távolságon belül hány elemet kapjunk meg (pl. ha csak 10 boltra vagyunk kíváncsiak, akkor a ROWNUM <= 10 értéket használhatjuk. Használható mind a kettő egyszerre is, lásd a lentebbi példákban. Egy egyszerűbb példa, amely visszaadja egy objektumhoz képest a legközelebbi objektumot:

select s1.id, s1.store, sdo_nn_distance(1) from store s1, store s2

WHERE SDO_NN(s2.EOV_ORACLE, s1.EOV_ORACLE, 'sdo_num_res=5') = 'TRUE' AND s1.store = 'TESCO'
A lekérdezéssel visszakapnánk az EOV-ban eltárolt objektumunkhoz legközelebbi 5 darab objektumot, ahol a store értéke 'TESCO', a sdo_num_res használatánál azonban a szűrés nem működik a célunknak megfelelően. Első körben ugyanis a sdo_num_res a legközelebbi 5 objektumra szűr rá, majd ezt követően ezen belül keresi meg a 'TESCO' értékkel rendelkezőket, ami nekünk jelen esetben nem a megfelelő eredmény. Ehelyett használhatjuk az sdo_batch_size függvényt:
select s1.id, s2.id as id2, sdo_nn_distance(s2.EOV_ORACLE, s1.EOV_ORACLE, 2) as distance from store s1, store s2

WHERE s1.store = 'TESCO' AND s2.id IN (SELECT ID FROM STORE s3 WHERE SDO_NN(s3.EOV_ORACLE, s1.EOV_ORACLE, 'sdo_batch_size=5') = 'TRUE' AND s3.store = 'TESCO' AND s3.ID != s1.ID AND ROWNUM <= 5;
Kicsit nyakatekertebb, de visszakapjuk a legközelebbi 5 db. TESCO-t, amit szerettünk volna.

A fenti alapinformációk alapján már egy robosztusabb alkalmazást is fel lehet építeni, erre egy konkrét példát ahamarosan megosztok Veletek, ahol egy általam fejlesztett automatikus körzetesítő alkalmazásról lesz szó.